package com.to8to.thrift.esb.async.example.server;

import io.netty.channel.ChannelHandlerContext;

import java.util.Map;

import org.apache.thrift.protocol.TMessageType;

import com.to8to.kitt.ThriftMessage;
import com.to8to.kitt.asyc.IMsgHandler;
import com.to8to.kitt.asyc.State;
import com.to8to.kitt.utils.NettyUtils;
import com.to8to.thrift.esb.async.example.ServiceA;
import com.to8to.thrift.esb.async.example.ServiceB;
import com.to8to.thrift.esb.async.example.ServiceC;
import com.to8to.thrift.esb.async.example.ServiceD;
import com.to8to.thrift.esb.async.example.TState;

public class ServiceA_Handler implements IMsgHandler{
	
	@Override
	public void handle(ChannelHandlerContext ctx, ThriftMessage inMsg, Map<Integer, State> states)
	{
		String name = inMsg.getHead().name;
		
		int seqid = inMsg.getSeqid();
		
		if(inMsg.isCall()) 
    	{
			if(name.contains(ServiceA.valueA_name))
			{
				ServiceA.valueA_args args = (ServiceA.valueA_args)inMsg.getBody();
				
				TState tstate = new TState();
				
				tstate.setSeqid(seqid);
				
				tstate.setD(args.d);
				
				State state = new State(seqid, this, tstate);
				
				states.put(seqid, state);
				
				ServiceB.valueB_args argsB = new ServiceB.valueB_args(args.b);
				
				NettyUtils.sendMsg(ctx, seqid, TMessageType.CALL, ServiceB.valueB_name, argsB);
			
				ServiceC.valueC_args argsC = new ServiceC.valueC_args(args.c);
				
				NettyUtils.sendMsg(ctx, seqid, TMessageType.CALL, ServiceC.valueC_name, argsC);
					
			}
			else if(name.contains(ServiceA.plus_name))
			{
				ServiceA.plus_args args = (ServiceA.plus_args)inMsg.getBody();
				ServiceA.plus_result result = new ServiceA.plus_result(args.a + args.b);
				NettyUtils.sendMsg(ctx, seqid, TMessageType.REPLY, ServiceA.plus_name, result);
			}
    	}
		else if(inMsg.isReply())
		{
			if(name.contains(ServiceB.valueB_name) || name.contains(ServiceC.valueC_name))
			{
				State state = states.get(seqid);
				
				if(state != null)
				{
					TState tstate = (TState)state.getData();
					
					if(tstate != null)
					{
						if(name.equals(ServiceB.valueB_name))
						{
							ServiceB.valueB_result result =  (ServiceB.valueB_result)inMsg.getBody();
							double b = result.getSuccess();
							tstate.setB(b);
						}
						else 
						{
							ServiceC.valueC_result result =  (ServiceC.valueC_result)inMsg.getBody();
							double c = result.getSuccess();
							tstate.setC(c);
						}
						
						if(tstate.isSetB() && tstate.isSetC())
						{
							double b_plus_c = tstate.getB() + tstate.getC();
							
							ServiceD.valueD_args argsD = new ServiceD.valueD_args(tstate.getD(), b_plus_c);
							
							NettyUtils.sendMsg(ctx, seqid, TMessageType.CALL, ServiceD.valueD_name, argsD);
							
						}
					}
				}
				
				
			}
			else if(name.contains(ServiceD.valueD_name))
			{
				State state = states.get(seqid);
				
				if(state != null)
				{
					TState tstate = (TState)state.getData();
					
					if(state != null)
					{
						ServiceD.valueD_result resultD = (ServiceD.valueD_result)inMsg.getBody();
						
						ServiceA.valueA_result resultA = new ServiceA.valueA_result(resultD.success);
						
						NettyUtils.sendMsg(ctx, tstate.seqid, TMessageType.REPLY, ServiceA.valueA_name, resultA);
						
						states.remove(seqid);
					}
				}
			}
		}
	}

	
}
